#ifndef ROCKET_NET_TCP_TCP_CLIENT_H
#define ROCKET_NET_TCP_TCP_CLIENT_H

#include <functional>

#include "../coder/abstract_protocol.h"
#include "../eventloop.h"
#include "net_addr.h"
#include "tcp_connection.h"
#include "timer_event.h"

namespace rocket {

class TcpClient {

  public:
    typedef std::shared_ptr<TcpClient> s_ptr;

    TcpClient(NetAddr::s_ptr peer_addr);

    ~TcpClient();

    // 异步 connect
    // done will be invoked when connect done
    void connect(std::function<void()> done);

    // 异步 send message
    void writeMessage(AbstractProtocol::s_ptr message,
                      std::function<void(AbstractProtocol::s_ptr)> done);

    // 异步 read message
    // 如果读取 message 成功，调用 done 函数 （message对象为参数）
    void readMessage(const std::string &req_id,
                     std::function<void(AbstractProtocol::s_ptr)> done);

    void stop();

    int getConnectErrorCode();

    std::string getConnectErrorInfo();

    NetAddr::s_ptr getPeerAddr();

    NetAddr::s_ptr getLocalAddr();

    void initLocalAddr();

    void addTimerEvent(TimerEvent::s_ptr timer_event);

  private:
    NetAddr::s_ptr m_peer_addr;
    NetAddr::s_ptr m_local_addr;
    EventLoop *m_event_loop{nullptr};

    int m_fd{-1};
    FdEvent *m_fd_event{nullptr};

    TcpConnection::s_ptr m_connection;

    int m_connect_error_code{0};
    std::string m_connect_error_info;
};

} // namespace rocket

#endif
